﻿using ScFramework.Core;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using CollisionHandler= System.Action<CollisionArgs, ISharedCollisionManager>;

public partial class CollisionManager : LogicDataModuleBase, ICollisionHandlerRegister,ICollisionManager
{
    public override void OnInit(object args)
    {
        base.OnInit(args);
        
    }
    protected ISubPhysicsManager subPhysicsManager;
    public void SetSubPhysicsMgr(ISubPhysicsManager m)
    {
        subPhysicsManager = m;
    }


    Dictionary<Tuple<ElementState, ElementState>, CollisionHandler> dicCache;
    #region handler
    List<Tuple<ElementState,ElementState, CollisionHandler>> handlerList;

    CollisionHandler defualtHandler = (CollisionArgs a, ISharedCollisionManager m) =>
    {
        if(a.Info is CollisionForceInfo f)
        {

            var s1 = m.GetInfo(a.StressingSystem, a.StressingID);
            var s2 = m.GetInfo(a.StressedSystem, a.StressedID);
            m.Damage(a.StressedSystem, a.StressedID,Mathf.RoundToInt(Mathf.Max(0,s1.Sharpness*(f.Force.magnitude-s2.Defence))));
        }
        else
        {
            Debug.LogError("Not found force info");
        }


 //       Debug.LogWarning("Not found handler");
    };
    public override void Init(SubmoduleBase p, object args = null)
    {
        base.Init(p, args);
        handlerList = new List<Tuple<ElementState, ElementState, CollisionHandler>>();
        dicCache = new Dictionary<Tuple<ElementState, ElementState>, CollisionHandler>();
    }


    public void RegisterCertainTypeHandler(ElementState stressingState, ElementState stressedState, CollisionHandler action)
    {
        Debug.Assert(handlerList.Find(s => s.Item1 == stressingState && s.Item2 == stressedState) == null);
        handlerList.Add(new Tuple<ElementState, ElementState, CollisionHandler>(stressingState, stressedState, action));
    }

    public void RegisterStressedTypeHandler(ElementState stressedState, CollisionHandler action)
    {
        ElementState stressingState = ElementState.Any;
        Debug.Assert(handlerList.Find(s => s.Item1 == stressingState && s.Item2 == stressedState) == null);
        handlerList.Add(new Tuple<ElementState, ElementState, CollisionHandler>(stressingState, stressedState, action));

    }

    public void RegisterStressingTypeHandler(ElementState stressingState, CollisionHandler action)
    {
        ElementState stressedState = ElementState.Any;
        Debug.Assert(handlerList.Find(s => s.Item1 == stressingState && s.Item2 == stressedState) == null);
        handlerList.Add(new Tuple<ElementState, ElementState, CollisionHandler>(stressingState, stressedState, action));
    }
    public CollisionHandler GetHandler(ElementState stressing,ElementState stressed)
    {
        if(dicCache.ContainsKey(new Tuple<ElementState, ElementState>(stressing, stressed)))
        {
            return dicCache[new Tuple<ElementState, ElementState>(stressing, stressed)];
        }
        CollisionHandler ans=null;
        //两个元素都匹配的
        if (handlerList.Find(s => s.Item1 == stressing && s.Item2 == stressed)!=null)
        {
            ans= handlerList.Find(s => s.Item1 == stressing && s.Item2 == stressed).Item3;
        }

        //第一个属性匹配,第二个属性为any
        if (handlerList.Find(s => s.Item1 == stressing&&s.Item2==ElementState.Any) != null)
        {
            ans= handlerList.Find(s => s.Item1 == stressing && s.Item2 == ElementState.Any).Item3;
        }
        //第二个属性匹配,第一个属性为any
        if (handlerList.Find(s => s.Item2 == stressed&&s.Item1==ElementState.Any) != null)
        {
            ans= handlerList.Find(s => s.Item2 == stressed && s.Item1 == ElementState.Any).Item3;
        }
        if (ans == null)
        {
            ans = defualtHandler;
        }
        return dicCache[new Tuple<ElementState, ElementState>(stressing, stressed)]=ans;
    }
   public  void SolveCollision()
    {
        var lists = GetInnerModule<IEntityMgrInner>().GetCollisionArgs();
        lists.AddRange(subPhysicsManager.GetCollisionArgs());

        foreach(var x in lists)
        {
            GetHandler(x.StressingState, x.StressedState)(x,this);
        }
    }





    #endregion


}
public interface ICollisionManager
{
    void SetSubPhysicsMgr(ISubPhysicsManager m);
    void SolveCollision();
}
public interface ICollisionHandlerRegister : IModuleInnerInterface
{
    void RegisterStressingTypeHandler(ElementState stressingState,CollisionHandler action);
    void RegisterStressedTypeHandler(ElementState stressedState,CollisionHandler action);

    void RegisterCertainTypeHandler(ElementState stressingState, ElementState stressedState, CollisionHandler action);

}

public abstract class CollisionBasicInfo
{
}
public class CollisionForceInfo:CollisionBasicInfo
{
    public Vector3 Force;
    public Vector3 WorldPos;
}
public enum BelongingSystem
{
    Default,
    Fluid,
    Ground
}

public class CollisionArgs : EventArgs
{
    /// <summary>
    /// 施力体的元素种类
    /// </summary>
    public ElementState StressingState;
    /// <summary>
    /// 施力体所属系统
    /// </summary>
    public BelongingSystem StressingSystem;
    /// <summary>
    /// 在系统内的id
    /// </summary>
    public uint StressingID;

    public ElementState StressedState;
    public BelongingSystem StressedSystem;
    public uint StressedID;

    public CollisionBasicInfo Info;
}